package boardgamer.yavalath.client.lobby;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.InputFilter;
import android.widget.EditText;
import boardgamer.common.client.Button;
import boardgamer.common.client.ClickableButton;
import boardgamer.common.client.Display;
import boardgamer.common.client.SimpleButton;
import boardgamer.common.client.layout.BitmapLayout;
import boardgamer.common.client.layout.LayoutGroup;
import boardgamer.common.client.layout.MutableTextLayout;
import boardgamer.yavalath.client.RenderHelper;
import boardgamer.yavalath.client.Settings;
import boardgamer.yavalath.client.resources.ImageHandler;
import boardgamer.yavalath.common.YavalathPlayerState;

/**
 * @author garysoed
 */
public class PlayerNamePicker implements Button {

  public final static float TEXT_MAX_HEIGHT_RATIO = 0.5f;
  public final static float TEXT_LEFT_HEIGHT_RATIO = 0.5f;
  public final static int MAX_CHAR_COUNT = 8;

  private final ClickableButton innerButton;
  private final NameDisplay nameDisplay;
  private final int playerId;
  private final EditText editText;
  private final AlertDialog nameDialog;
  private boolean isClosed;

  public PlayerNamePicker(int playerId, int color, boolean isClosed, Context context) {
    Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    backgroundPaint.setColorFilter(new LightingColorFilter(color, 0));

    this.nameDisplay = new NameDisplay(backgroundPaint);
    this.innerButton = new ClickableButton(
        new SimpleButton(
            nameDisplay,
            new EventHandler() {
              @Override
              public void onEvent(float eventX, float eventY, int eventAction) {
                editName();
              }
            },
            nameDisplay.getBoundingRect()),
        new BitmapLayout(ImageHandler.playerNameBackgroundGlow, backgroundPaint));

    this.playerId = playerId;
    this.isClosed = isClosed;
    this.editText = new EditText(context);
    this.editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(8) });

    this.nameDialog = new AlertDialog.Builder(context)
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialogInterface, int i) {
            setPlayerName(editText.getText().toString());
            dialogInterface.dismiss();
          }
        })
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialogInterface, int i) {
            dialogInterface.dismiss();
          }
        })
        .setTitle("Set player " + (playerId + 1) + "'s name")
        .create();
    this.nameDialog.setView(editText, 25, 10, 25, 25);
    refreshPlayerName();
  }

  public void setPlayerMode(YavalathPlayerState.PlayerMode nextMode) {
    switch (nextMode) {
      case CLOSED:
        isClosed = true;
        break;
      case AI:
      case HUMAN:
        isClosed = false;
        break;
    }
  }

  public void refreshPlayerName() {
    setPlayerName(getPlayerName());
  }
  
  private void setPlayerName(String playerName) {
    nameDisplay.playerNameLayout.setText(playerName);
    Settings.instance().setPlayerName(playerId, playerName);
  }

  private void editName() {
    editText.setText(getPlayerName());
    nameDialog.show();
  }

  @Override
  public void draw(Canvas canvas) {
    if (!isClosed) {
      innerButton.draw(canvas);
    }
  }

  @Override
  public void setBoundingRect(RectF boundingRect) {
    innerButton.setBoundingRect(boundingRect);
  }

  @Override
  public RectF getBoundingRect() {
    return innerButton.getBoundingRect();
  }

  public String getPlayerName() {
    return Settings.instance().getPlayer(playerId).getName();
  }

  @Override
  public void handleEvent(float eventX, float eventY, int eventAction) {
    innerButton.handleEvent(eventX, eventY, eventAction);
  }

  @Override
  public RectF getCollisionBox() {
    return innerButton.getCollisionBox();
  }

  private static class NameDisplay implements Display {

    private final BitmapLayout background;
    public final MutableTextLayout playerNameLayout;
    private final LayoutGroup group;

    public NameDisplay(Paint paint) {
      this.background = new BitmapLayout(ImageHandler.playerNameBackground, paint);

      Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      textPaint.setColor(Color.BLACK);
      textPaint.setTypeface(ImageHandler.headingFont);
      textPaint.setTextSize(RenderHelper.instance().getMaxFittingHeightTextSize(
          this.background.getBoundingRect().height() * TEXT_MAX_HEIGHT_RATIO,
          ImageHandler.headingFont));
      this.playerNameLayout = new MutableTextLayout(
          textPaint,
          background.getBoundingRect().width()
              - background.getBoundingRect().height() * TEXT_LEFT_HEIGHT_RATIO,
          MAX_CHAR_COUNT,
          LayoutGroup.HorizontalAlign.LEFT,
          ImageHandler.boundSizeRatio.get(RenderHelper.instance().getHexLetterFont()));

      this.group = new LayoutGroup()
          .add(background).atCurrentRect()
          .add(playerNameLayout).atPosition(
              background.getBoundingRect().height() * TEXT_LEFT_HEIGHT_RATIO,
              0)
          .verticalAlign(LayoutGroup.VerticalAlign.CENTER);
    }

    @Override
    public void draw(Canvas canvas) {
      background.draw(canvas);
      playerNameLayout.draw(canvas);
    }

    @Override
    public void setBoundingRect(RectF boundingRect) {
      group.setBoundingRect(boundingRect);
    }

    @Override
    public RectF getBoundingRect() {
      return group.getBoundingRect();
    }
  }
}
